Skip to content

feat(ai): resolve topic explanations server-side for follow-up chat#58

Merged
imuniqueshiv merged 15 commits into
mainfrom
HyperAIWorkspace1
Jul 6, 2026
Merged

feat(ai): resolve topic explanations server-side for follow-up chat#58
imuniqueshiv merged 15 commits into
mainfrom
HyperAIWorkspace1

Conversation

@imuniqueshiv

@imuniqueshiv imuniqueshiv commented Jul 6, 2026

Copy link
Copy Markdown
Owner

Pull Request

Summary

Improve the AI workspace follow-up chat flow by resolving topic explanations server-side. This removes the dependency on client-provided cached explanations, improves reliability, and ensures follow-up questions work consistently in production.


Related Issue

N/A


Type of Change

  • Feature
  • Bug Fix
  • Documentation
  • Refactor
  • Performance Improvement
  • CI / Build
  • Other

What Changed?

  • Added a new server-side topic explanation resolver with cache-aware fallback.
  • Updated the AI workspace API to resolve explanations from the server instead of relying on client-provided cached data.
  • Improved follow-up question generation by automatically retrieving or generating the required topic explanation when needed.
  • Simplified the client-side follow-up workflow and improved loading and error handling.
  • Enhanced the overall reliability of AI workspace conversations for production use.

Screenshots (UI Changes Only)

N/A (No visual UI changes)


Testing

  • Verified initial topic explanation generation.
  • Verified cached explanations are reused when available.
  • Verified follow-up questions work correctly after page refresh.
  • Verified server-side fallback generates explanations when the cache is unavailable.
  • Ran npm run format:check.
  • Ran npm run lint.
  • Ran npm run typecheck.
  • Ran npm run build.

Checklist

  • My branch is up to date with the latest main.
  • My code follows the project's coding standards.
  • I have formatted the modified files.
  • npm run format:check passes.
  • npm run lint passes.
  • npm run typecheck passes.
  • npm run build passes.
  • Documentation updates were not required.
  • I have tested my changes locally.
  • This Pull Request focuses on a single feature.

Additional Notes

This update improves the robustness of the AI workspace by ensuring follow-up conversations no longer depend on client-side cached explanations. Topic explanations are now resolved server-side with cache-aware fallback, providing a more reliable and production-ready experience.

Summary by CodeRabbit

  • New Features

    • Follow-up chat responses now load topic explanations automatically from the selected topic context.
    • The chat UI now shows clearer loading, readiness, and follow-up states before you can continue.
  • Bug Fixes

    • Improved error messages when the AI service is unavailable or not configured.
    • Send controls now stay disabled until the topic explanation is ready, preventing incomplete requests.

@vercel

vercel Bot commented Jul 6, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
hyper-learning-tech Ready Ready Preview, Comment Jul 6, 2026 4:23am

@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds a resolveTopicExplanation module that fetches topic metadata and answer cache, integrates it into the AI workspace API route's follow-up validation flow, refines error responses for missing API key/Gemini, and reworks WorkspaceChat to fetch and gate UI state on topic-context readiness and explanation loading.

Changes

Topic Explanation Resolution and Workspace Integration

Layer / File(s) Summary
resolveTopicExplanation module
lib/ai/resolve-topic-explanation.ts
New module with ResolveTopicContext/ResolvedTopic interfaces; resolver loads topic via getTopicById, checks getTopicCache, and falls back to generateTopicAnswer with action "EXPLAIN" when uncached.
API route follow-up validation and error handling
app/api/ai/workspace/route.ts
POST handler imports and calls resolveTopicExplanation to derive topic, moduleTitle, cachedExplanation from subjectCode/branch/semester/topicId, replacing prior direct-field requirements; catch block returns a distinct "AI service not configured" message for API key/Gemini errors.
WorkspaceChat explanation state and fetch effect
components/ai/workspace-chat.tsx
Introduces isTopicContextReady, isFollowupMode, activeExplanation, explanationLoading/explanationCached state, and a cancellable useEffect with explanationRequestedRef that fetches the explanation once via EXPLAIN action, seeding the initial assistant message; request payload and send-blocking logic updated accordingly.
WorkspaceChat conditional rendering updates
components/ai/workspace-chat.tsx
Follow-up section, empty state, explanation status text, suggested follow-ups, footer routing, and textarea/button disablement conditionals switched from isFollowupMode/cachedExplanation to isTopicContextReady/activeExplanation/explanationLoading.

Estimated code review effort: 3 (Moderate) | ~30 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant WorkspaceChat
  participant WorkspaceRoute as API route
  participant Resolver as resolveTopicExplanation

  User->>WorkspaceChat: Select topic context
  WorkspaceChat->>WorkspaceChat: isTopicContextReady = true
  WorkspaceChat->>WorkspaceRoute: POST action=EXPLAIN (branch, semester, topicId, subjectCode)
  WorkspaceRoute->>Resolver: resolveTopicExplanation(context)
  Resolver-->>WorkspaceRoute: topic, module, explanation, cached
  WorkspaceRoute-->>WorkspaceChat: explanation response
  WorkspaceChat->>WorkspaceChat: set topicExplanation, explanationCached, explanationLoading=false
  WorkspaceChat-->>User: Render initial assistant explanation
  User->>WorkspaceChat: Send follow-up question
  WorkspaceChat->>WorkspaceRoute: POST question with topic context
  WorkspaceRoute-->>WorkspaceChat: follow-up answer
  WorkspaceChat-->>User: Render follow-up response
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: server-side resolution of topic explanations for follow-up chat.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch HyperAIWorkspace1

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@imuniqueshiv imuniqueshiv merged commit 9debf3c into main Jul 6, 2026
5 checks passed
@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown

🎉 Congratulations @imuniqueshiv!

Thank you for contributing to HyperLearningTech.

Your pull request has been successfully merged into main.

📦 Merge Summary

🚀 Keep Contributing

  • Follow the CONTRIBUTING.md guidelines.
  • Keep each Pull Request focused on a single feature or fix.
  • Run formatting, linting, type checking, and a production build before opening a PR.

Thank you for helping make HyperLearningTech better.

Happy Coding! 🚀

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
app/api/ai/workspace/route.ts (1)

66-76: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Short-circuit resolveTopicExplanation when the body already carries topic context.

resolveTopicExplanation is awaited unconditionally before the body.* precedence is applied. On a server-side cache miss this delegates to generateTopicAnswer(action: "EXPLAIN"), so a fresh (and costly) LLM explanation is generated even when the client already supplied topic, module, and cachedExplanation. Only resolve when one of them is missing.

♻️ Proposed guard
-      const resolved = await resolveTopicExplanation({
-        branch,
-        semester,
-        topicId,
-        subjectCode,
-      });
-
-      const topic = body.topic?.trim() || resolved.topic;
-      const moduleTitle = body.module?.trim() || resolved.module;
-      const cachedExplanation =
-        body.cachedExplanation?.trim() || resolved.explanation;
+      let topic = body.topic?.trim();
+      let moduleTitle = body.module?.trim();
+      let cachedExplanation = body.cachedExplanation?.trim();
+
+      if (!topic || !moduleTitle || !cachedExplanation) {
+        const resolved = await resolveTopicExplanation({
+          branch,
+          semester,
+          topicId,
+          subjectCode,
+        });
+        topic = topic || resolved.topic;
+        moduleTitle = moduleTitle || resolved.module;
+        cachedExplanation = cachedExplanation || resolved.explanation;
+      }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/api/ai/workspace/route.ts` around lines 66 - 76, The
`resolveTopicExplanation` call in `route.ts` is being awaited even when
`body.topic`, `body.module`, and `body.cachedExplanation` already provide all
needed context, which can trigger an unnecessary `generateTopicAnswer` lookup
and LLM explanation. Update the workspace route handler to short-circuit this
path: only call `resolveTopicExplanation` when at least one of the three body
fields is missing, and otherwise use the trimmed body values directly. Keep the
fallback behavior intact for partial payloads by preserving the existing
precedence logic around `resolved.topic`, `resolved.module`, and
`resolved.explanation`.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@components/ai/workspace-chat.tsx`:
- Around line 111-190: Reset the explanation request state when the active topic
changes, and align the workspace payload with the route’s expected contract. In
`WorkspaceChat`, make sure `explanationRequestedRef` is cleared on `topicId`
changes so a new topic can fetch its own explanation, and ensure
`setExplanationLoading(false)` still runs after canceled requests. Also update
the non-topic request path in `workspace-chat.tsx` to send the full context
expected by the API, or adjust `workspace/route.ts` so plain `question` requests
are not treated as follow-ups unless `branch`, `semester`, and `topicId` are
present.

---

Nitpick comments:
In `@app/api/ai/workspace/route.ts`:
- Around line 66-76: The `resolveTopicExplanation` call in `route.ts` is being
awaited even when `body.topic`, `body.module`, and `body.cachedExplanation`
already provide all needed context, which can trigger an unnecessary
`generateTopicAnswer` lookup and LLM explanation. Update the workspace route
handler to short-circuit this path: only call `resolveTopicExplanation` when at
least one of the three body fields is missing, and otherwise use the trimmed
body values directly. Keep the fallback behavior intact for partial payloads by
preserving the existing precedence logic around `resolved.topic`,
`resolved.module`, and `resolved.explanation`.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 32886c84-b2aa-43eb-aeea-5eda1ca01054

📥 Commits

Reviewing files that changed from the base of the PR and between 74898ad and e7466f8.

📒 Files selected for processing (3)
  • app/api/ai/workspace/route.ts
  • components/ai/workspace-chat.tsx
  • lib/ai/resolve-topic-explanation.ts

Comment on lines +111 to +190
const explanationRequestedRef = useRef(false);

useEffect(() => {
if (
!isTopicContextReady ||
topicExplanation ||
cachedExplanation ||
explanationRequestedRef.current
) {
return;
}

explanationRequestedRef.current = true;
let cancelled = false;

const loadExplanation = async () => {
setExplanationLoading(true);
setError(null);

try {
const response = await fetch(apiEndpoint, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
branch,
semester,
topicId,
subjectCode,
action: "EXPLAIN",
}),
});

const data = (await response.json()) as WorkspaceResponse;

if (cancelled) return;

if (!response.ok || !data.answer) {
throw new Error(data.error || "Failed to load topic explanation.");
}

setTopicExplanation(data.answer);
setExplanationCached(data.cached);
setMessages([
{
id: "initial-cached-explanation",
role: "assistant",
content: data.answer,
timestamp: new Date(),
},
]);
} catch (err: unknown) {
if (!cancelled) {
setError(
err instanceof Error
? err.message
: "Failed to load topic explanation."
);
}
} finally {
if (!cancelled) {
setExplanationLoading(false);
}
}
};

void loadExplanation();

return () => {
cancelled = true;
};
}, [
apiEndpoint,
branch,
cachedExplanation,
isTopicContextReady,
semester,
subjectCode,
topicExplanation,
topicId,
]);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
rg -nP -C4 '<WorkspaceChat\b' --type=tsx --type=ts
rg -nP -C3 'key=' $(fd -tf 'workspace-chat' -e tsx) 2>/dev/null

Repository: imuniqueshiv/HyperLearningTech

Length of output: 2018


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Locate the API route and the component usages relevant to topic switching/remounting.
rg -n --hidden --glob '!node_modules' --glob '!dist' --glob '!build' '/api/ai/workspace|workspace-chat|WorkspaceChat|topicId|branch|semester' components app pages src 2>/dev/null || true

# Inspect the workspace chat component around the effect and render paths.
file="components/ai/workspace-chat.tsx"
if [ -f "$file" ]; then
  nl -ba "$file" | sed -n '1,260p'
fi

# Find the workspace API route file(s).
fd -tf 'workspace' app api pages src 2>/dev/null || true

Repository: imuniqueshiv/HyperLearningTech

Length of output: 15667


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Read the relevant source slices directly.
for file in \
  "components/ai/workspace-chat.tsx" \
  "components/ai/workspace-chat-loader.tsx" \
  "app/api/ai/workspace/route.ts" \
  "app/rgpv/[branch]/[semester]/[subject]/ai/page.tsx"
do
  if [ -f "$file" ]; then
    echo "===== $file ====="
    sed -n '1,260p' "$file"
    echo
  fi
done

Repository: imuniqueshiv/HyperLearningTech

Length of output: 18876


Fix the workspace payload and reset the explanation request per topic.

  • components/ai/workspace-chat.tsx: explanationRequestedRef never resets, so a topicId change can reuse stale explanation state; if the in-flight request is canceled, explanationLoading can also stay stuck.
  • app/api/ai/workspace/route.ts / components/ai/workspace-chat.tsx: the non-topic path sends question without topic context, but the route treats every question as follow-up and now requires branch, semester, and topicId, so general questions return 400.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/ai/workspace-chat.tsx` around lines 111 - 190, Reset the
explanation request state when the active topic changes, and align the workspace
payload with the route’s expected contract. In `WorkspaceChat`, make sure
`explanationRequestedRef` is cleared on `topicId` changes so a new topic can
fetch its own explanation, and ensure `setExplanationLoading(false)` still runs
after canceled requests. Also update the non-topic request path in
`workspace-chat.tsx` to send the full context expected by the API, or adjust
`workspace/route.ts` so plain `question` requests are not treated as follow-ups
unless `branch`, `semester`, and `topicId` are present.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant